package com.zjj.algorithm.learning.leetcode.stack;

import java.util.Stack;

/**
 * 150. 逆波兰表达式求值 中档
 * <p>
 * 根据 逆波兰表示法，求表达式的值。
 * <p>
 * 有效的算符包括 +、-、*、/ 。每个运算对象可以是整数，也可以是另一个逆波兰表达式。
 * <p>
 * 注意 两个整数之间的除法只保留整数部分。
 * <p>
 * 可以保证给定的逆波兰表达式总是有效的。换句话说，表达式总会得出有效数值且不存在除数为 0 的情况。
 * <p>
 * 示例 1：
 * <p>
 * 输入：tokens = ["2","1","+","3","*"]
 * 输出：9
 * 解释：该算式转化为常见的中缀算术表达式为：((2 + 1) * 3) = 9
 * 示例 2：
 * <p>
 * 输入：tokens = ["4","13","5","/","+"]
 * 输出：6
 * 解释：该算式转化为常见的中缀算术表达式为：(4 + (13 / 5)) = 6
 *
 * @author zjj_admin
 * @date 2022/11/17 14:31
 */
public class EvaluateReversePolishNotation {

    public static void main(String[] args) {
        String[] tokens = new String[]{"10","6","9","3","+","-11","*","/","*","17","+","5","+"};
        int res = evalRPN(tokens);
        System.out.println("res = " + res);
    }


    /**
     * 时间
     * 7 ms
     * 击败
     * 21.50%
     * 内存
     * 41.2 MB
     * 击败
     * 40.10%
     * @param tokens
     * @return
     */
    public static int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        int res = 0;
        for (int i = 0; i < tokens.length; i++) {
            String ele = tokens[i];
            if(isNumber(ele)){
                stack.push(Integer.parseInt(ele));
            }else {
                //取出两个数
                int num2 = stack.pop();
                int num1 = stack.pop();
                switch (ele) {
                    case "+":
                        stack.push(num1 + num2);
                        break;
                    case "-":
                        stack.push(num1 - num2);
                        break;
                    case "*":
                        stack.push(num1 * num2);
                        break;
                    case "/":
                        stack.push(num1 / num2);
                        break;
                    default:
                }
            }
        }
        return stack.pop();
    }

    public static boolean isNumber(String ele) {
        return !("+".equals(ele) || "-".equals(ele) || "*".equals(ele) || "/".equals(ele));
    }
}
